using System;
using System.Collections.Generic;
using System.Data;

using PMServiceDesk.DataType;
using PMServiceDesk.Utils.ManejoDatos;
using PMServiceDesk.Parameters.Constantes;

namespace PMServiceDesk.DataAccess
{
    public class PaqueteTrabajoData
    {
        #region Variables

        private string _select;
        private string _join;
        private string _where;
        private int _totalRegistros = 0;

        private Dictionary<string, object> _parametrosConsulta;

        #endregion

        #region Propiedades

        protected string Where
        {
            get
            {
                if (_where == "") return "";

                return "WHERE " + _where.Substring(3);
            }
        }

        #endregion

        #region Constructores

        public PaqueteTrabajoData()
        {
            this._limpiarConsulta();
        }

        #endregion

        #region Metodos

        private void _limpiarConsulta()
        {
            _select = "";
            _join = "";
            _where = "";
            _parametrosConsulta = new Dictionary<string, object>();
        }

        private DataUtil _consultaDataReader(int paginaActual = 0, int cantidadMostrar = 0, string orderBy = "")
        {
            DataUtil data = null;

            if(paginaActual==0)
                data = new DataUtil(TypeDataBase.PMServiceDesk, CommandType.Text, _select + _join + this.Where + orderBy,_parametrosConsulta);
            else
                data = DataReader.ReturnPagingReader(TypeDataBase.PMServiceDesk, _select, _join, this.Where, this._parametrosConsulta, paginaActual, cantidadMostrar, orderBy, ref _totalRegistros);

            this._limpiarConsulta();

            return data;
        }

        public void Grabar(PaqueteTrabajoType paqueteTrabajo)
        {
            using (DataUtil d = this._grabar())
            {
                d.AddParameter("@ID", (paqueteTrabajo.Id == null ? "0" : paqueteTrabajo.Id));
                d.AddParameter("@PROYECTOID", paqueteTrabajo.ProyectoId);
                d.AddParameter("@TIPOPAQUETETRABAJOID", paqueteTrabajo.TipoPaqueteTrabajoId);
                d.AddParameter("@USUARIORESPONSABLEID", paqueteTrabajo.UsuarioResponsableId);
                d.AddParameter("@USUARIOASIGNADOID", paqueteTrabajo.UsuarioAsignadoId);
                d.AddParameter("@ESTADOPAQUETETRABAJOID", paqueteTrabajo.EstadoPaqueteTrabajoId);
                d.AddParameter("@CODIGOCUENTA", paqueteTrabajo.CodigoCuenta);
                d.AddParameter("@NOMBRE", paqueteTrabajo.Nombre);
                d.AddParameter("@DESCRIPCION", paqueteTrabajo.Descripcion);
                d.AddParameter("@FECHAINICIOPROYECTADO", ConvertFormat.Char_To_DateOrNull(paqueteTrabajo.FechaInicioProyectado));
                d.AddParameter("@FECHAFINPROYECTADO", ConvertFormat.Char_To_DateOrNull(paqueteTrabajo.FechaFinProyectado));
                d.AddParameter("@FECHAINICIOREAL", ConvertFormat.Char_To_DateOrNull(paqueteTrabajo.FechaInicioReal));
                d.AddParameter("@FECHAFINREAL", ConvertFormat.Char_To_DateOrNull(paqueteTrabajo.FechaFinReal));
                d.AddParameter("@PORCENTAJEAVANCE", paqueteTrabajo.PorcentajeAvance);

                paqueteTrabajo.Id = d.ExecuteScalar(true).ToString();
            }
        }

        public PaqueteTrabajoType Cargar()
        {
            List<PaqueteTrabajoType> l = this.CargarLista();

            if (l.Count == 0) return null;

            return l[0];
        }

        public List<PaqueteTrabajoType> CargarLista()
        {
            List<PaqueteTrabajoType> l = new List<PaqueteTrabajoType>();

            using (DataUtil d = this._consultaCargar())
                using (IDataReader r = d.ExecuteReader())
                {
                    PaqueteTrabajoType o = null;

                    while (r.Read())
                    {
                        o = new PaqueteTrabajoType();

                        o.Id = r.GetValue(d.GetOrdinalReader("ID")).ToString();
                        o.ProyectoId = r.GetValue(d.GetOrdinalReader("PROYECTOID")).ToString();
                        o.TipoPaqueteTrabajoId = r.GetValue(d.GetOrdinalReader("TIPOPAQUETETRABAJOID")).ToString();
                        o.TipoPaqueteTrabajo = r.GetValue(d.GetOrdinalReader("TIPOPAQUETETRABAJO")).ToString();
                        o.UsuarioResponsableId = r.GetValue(d.GetOrdinalReader("USUARIORESPONSABLEID")).ToString();
                        o.UsuarioResponsable = r.GetValue(d.GetOrdinalReader("USUARIORESPONSABLE")).ToString();
                        o.UsuarioAsignadoId = r.GetValue(d.GetOrdinalReader("USUARIOASIGNADOID")).ToString();
                        o.UsuarioAsignado = r.GetValue(d.GetOrdinalReader("USUARIOASIGNADO")).ToString();
                        o.EstadoPaqueteTrabajoId = r.GetValue(d.GetOrdinalReader("ESTADOPAQUETETRABAJOID")).ToString();
                        o.EstadoPaqueteTrabajo = r.GetValue(d.GetOrdinalReader("ESTADOPAQUETETRABAJO")).ToString();
                        o.CodigoCuenta = r.GetValue(d.GetOrdinalReader("CODIGOCUENTA")).ToString();
                        o.Nombre = r.GetValue(d.GetOrdinalReader("NOMBRE")).ToString();
                        o.Descripcion = r.GetValue(d.GetOrdinalReader("DESCRIPCION")).ToString();
                        o.FechaInicioProyectado = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAINICIOPROYECTADO")));
                        o.FechaFinProyectado = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAFINPROYECTADO")));
                        o.FechaInicioReal = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAINICIOREAL")).ToString());
                        o.FechaFinReal = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAFINREAL")).ToString());
                        o.PorcentajeAvance = ConvertFormat.Char_To_Decimal(r.GetValue(d.GetOrdinalReader("PORCENTAJEAVANCE")));
                        o.PorcentajeAvance_Format = ConvertFormat.Decimal_To_Char(o.PorcentajeAvance) + " %";

                        l.Add(o);
                    }
                }

            return l;
        }

        public List<PaqueteTrabajoType> CargarListaVista(int paginaActual = 0, int cantidadMostrar = 0, string orderBy = "")
        {
            List<PaqueteTrabajoType> l = new List<PaqueteTrabajoType>();

            using (DataUtil d = this._consultaCargarVista(paginaActual, cantidadMostrar,orderBy))
                using (IDataReader r = d.ExecuteReader())
                {
                    PaqueteTrabajoType o = null;

                    while (r.Read())
                    {
                        o = new PaqueteTrabajoType();

                        o.Id = r.GetValue(d.GetOrdinalReader("ID")).ToString();
                        o.ProyectoId = r.GetValue(d.GetOrdinalReader("PROYECTOID")).ToString();
                        o.TipoPaqueteTrabajoId = r.GetValue(d.GetOrdinalReader("TIPOPAQUETETRABAJOID")).ToString();
                        o.TipoPaqueteTrabajo = r.GetValue(d.GetOrdinalReader("TIPOPAQUETETRABAJO")).ToString();
                        o.UsuarioResponsableId = r.GetValue(d.GetOrdinalReader("USUARIORESPONSABLEID")).ToString();
                        o.UsuarioResponsable = r.GetValue(d.GetOrdinalReader("USUARIORESPONSABLE")).ToString();
                        o.UsuarioAsignadoId = r.GetValue(d.GetOrdinalReader("USUARIOASIGNADOID")).ToString();
                        o.UsuarioAsignado = r.GetValue(d.GetOrdinalReader("USUARIOASIGNADO")).ToString();
                        o.EstadoPaqueteTrabajoId = r.GetValue(d.GetOrdinalReader("ESTADOPAQUETETRABAJOID")).ToString();
                        o.EstadoPaqueteTrabajo = r.GetValue(d.GetOrdinalReader("ESTADOPAQUETETRABAJO")).ToString();
                        o.CodigoCuenta = r.GetValue(d.GetOrdinalReader("CODIGOCUENTA")).ToString();
                        o.Nombre = r.GetValue(d.GetOrdinalReader("NOMBRE")).ToString();
                        o.Descripcion = r.GetValue(d.GetOrdinalReader("DESCRIPCION")).ToString();
                        o.FechaInicioProyectado = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAINICIOPROYECTADO")));
                        o.FechaFinProyectado = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAFINPROYECTADO")));
                        o.FechaInicioReal = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAINICIOREAL")).ToString());
                        o.FechaFinReal = ConvertFormat.Date_To_Char(r.GetValue(d.GetOrdinalReader("FECHAFINREAL")).ToString());
                        o.PorcentajeAvance = ConvertFormat.Char_To_Decimal(r.GetValue(d.GetOrdinalReader("PORCENTAJEAVANCE")));
                        o.PorcentajeAvance_Format = ConvertFormat.Decimal_To_Char(o.PorcentajeAvance) + " %";

                        l.Add(o);
                    }
                }

            if (l.Count <= _totalRegistros) l.Capacity = _totalRegistros;

            return l;
        }

        #endregion

        #region SQL

        private DataUtil _grabar()
        {
            string sql = @"IF(NOT EXISTS(SELECT 1 FROM PAQUETETRABAJO WHERE ID=@ID)) 
                           BEGIN
                               INSERT INTO PAQUETETRABAJO
                               (
                                   PROYECTOID
                                  ,TIPOPAQUETETRABAJOID
                                  ,USUARIORESPONSABLEID
                                  ,USUARIOASIGNADOID
                                  ,ESTADOPAQUETETRABAJOID
                                  ,CODIGOCUENTA
                                  ,NOMBRE
                                  ,DESCRIPCION
                                  ,FECHAINICIOPROYECTADO
                                  ,FECHAFINPROYECTADO
                                  ,FECHAINICIOREAL
                                  ,FECHAFINREAL
                                  ,PORCENTAJEAVANCE
                               )
                               VALUES
                               (
                                   @PROYECTOID
                                  ,@TIPOPAQUETETRABAJOID
                                  ,@USUARIORESPONSABLEID
                                  ,@USUARIOASIGNADOID
                                  ,@ESTADOPAQUETETRABAJOID
                                  ,@CODIGOCUENTA
                                  ,@NOMBRE
                                  ,@DESCRIPCION
                                  ,@FECHAINICIOPROYECTADO
                                  ,@FECHAFINPROYECTADO
                                  ,@FECHAINICIOREAL
                                  ,@FECHAFINREAL
                                  ,@PORCENTAJEAVANCE
                               )

                               SELECT @@IDENTITY
                           END
                           ELSE
                           BEGIN
                               UPDATE PAQUETETRABAJO SET
                               PROYECTOID=@PROYECTOID
                              ,TIPOPAQUETETRABAJOID=@TIPOPAQUETETRABAJOID
                              ,USUARIORESPONSABLEID=@USUARIORESPONSABLEID
                              ,USUARIOASIGNADOID=@USUARIOASIGNADOID
                              ,ESTADOPAQUETETRABAJOID=@ESTADOPAQUETETRABAJOID
                              ,CODIGOCUENTA=@CODIGOCUENTA
                              ,NOMBRE=@NOMBRE
                              ,DESCRIPCION=@DESCRIPCION
                              ,FECHAINICIOPROYECTADO=@FECHAINICIOPROYECTADO
                              ,FECHAFINPROYECTADO=@FECHAFINPROYECTADO
                              ,FECHAINICIOREAL=@FECHAINICIOREAL
                              ,FECHAFINREAL=@FECHAFINREAL
                              ,PORCENTAJEAVANCE=@PORCENTAJEAVANCE
                               WHERE ID=@ID

                               SELECT @ID
                           END";

            return new DataUtil(TypeDataBase.PMServiceDesk, CommandType.Text, sql);
        }

        private DataUtil _consultaCargar()
        {
            _select = @"SELECT
                        PA.ID
                        ,PA.PROYECTOID
                        ,PA.TIPOPAQUETETRABAJOID
                        ,TIPPAQ.NOMBRE						[TIPOPAQUETETRABAJO]
                        ,PA.USUARIORESPONSABLEID
                        ,RECRESP.NOMBRE						[USUARIORESPONSABLE]
                        ,PA.USUARIOASIGNADOID
                        ,RECASIG.NOMBRE                     [USUARIOASIGNADO]
                        ,PA.ESTADOPAQUETETRABAJOID
                        ,EST.NOMBRE							[ESTADOPAQUETETRABAJO]
                        ,PA.CODIGOCUENTA
                        ,PA.NOMBRE
                        ,PA.DESCRIPCION
                        ,PA.FECHAINICIOPROYECTADO
                        ,PA.FECHAFINPROYECTADO
                        ,PA.FECHAINICIOREAL
                        ,PA.FECHAFINREAL
                        ,PA.PORCENTAJEAVANCE
                        ";

            _join = @"FROM DBO.PAQUETETRABAJO [PA] 
                    INNER JOIN USUARIORECURSO [RESP] ON RESP.USUARIOID = PA.USUARIORESPONSABLEID
                    INNER JOIN RECURSO [RECRESP] ON RECRESP.ID = RESP.RECURSOID AND RECRESP.PROYECTOID = PA.PROYECTOID
                    INNER JOIN DBO.TIPOPAQUETETRABAJO [TIPPAQ] ON TIPPAQ.ID=PA.TIPOPAQUETETRABAJOID
                    INNER JOIN DBO.ESTADOPAQUETETRABAJO [EST] ON EST.ID=PA.ESTADOPAQUETETRABAJOID
                    LEFT JOIN USUARIORECURSO [ASIG] ON ASIG.USUARIOID = PA.USUARIOASIGNADOID
                    LEFT JOIN RECURSO [RECASIG] ON RECASIG.ID = ASIG.RECURSOID AND RECASIG.PROYECTOID = PA.PROYECTOID
                      ";

            return this._consultaDataReader();
        }

        private DataUtil _consultaCargarVista(int paginaActual = 0, int cantidadMostrar = 0, string orderBy = "")
        {
            _select = @"SELECT
                        PA.ID
                        ,PA.PROYECTOID
                        ,PA.TIPOPAQUETETRABAJOID
                        ,TIPPAQ.NOMBRE						[TIPOPAQUETETRABAJO]
                        ,PA.USUARIORESPONSABLEID
                        ,RECRESP.NOMBRE						[USUARIORESPONSABLE]
                        ,PA.USUARIOASIGNADOID
                        ,RECASIG.NOMBRE                     [USUARIOASIGNADO]
                        ,PA.ESTADOPAQUETETRABAJOID
                        ,EST.NOMBRE							[ESTADOPAQUETETRABAJO]
                        ,PA.CODIGOCUENTA
                        ,PA.NOMBRE
                        ,PA.DESCRIPCION
                        ,PA.FECHAINICIOPROYECTADO
                        ,PA.FECHAFINPROYECTADO
                        ,PA.FECHAINICIOREAL
                        ,PA.FECHAFINREAL
                        ,PA.PORCENTAJEAVANCE
                        ";

            _join = @"FROM DBO.PAQUETETRABAJO [PA] 
                    INNER JOIN USUARIORECURSO [RESP] ON RESP.USUARIOID = PA.USUARIORESPONSABLEID
                    INNER JOIN RECURSO [RECRESP] ON RECRESP.ID = RESP.RECURSOID AND RECRESP.PROYECTOID = PA.PROYECTOID
                    INNER JOIN DBO.TIPOPAQUETETRABAJO [TIPPAQ] ON TIPPAQ.ID=PA.TIPOPAQUETETRABAJOID
                    INNER JOIN DBO.ESTADOPAQUETETRABAJO [EST] ON EST.ID=PA.ESTADOPAQUETETRABAJOID
                    LEFT JOIN USUARIORECURSO [ASIG] ON ASIG.USUARIOID = PA.USUARIOASIGNADOID
                    LEFT JOIN RECURSO [RECASIG] ON RECASIG.ID = ASIG.RECURSOID AND RECASIG.PROYECTOID = PA.PROYECTOID
                      ";

            return this._consultaDataReader(paginaActual, cantidadMostrar, orderBy);
        }

        public void FiltrarPorId(string id)
        {
            _where += @"AND PA.ID=@ID
                                 ";

            _parametrosConsulta.Add("@ID", id);
        }
        public void FiltrarPorCodigoCuenta(string codigoCuenta)
        {
            _where += @"AND PA.CODIGOCUENTA=@CODIGOCUENTA
                                 ";

            _parametrosConsulta.Add("@CODIGOCUENTA", codigoCuenta);
        }
        public void FiltrarPorProyectoId(string proyectoId)
        {
            _where += @"AND PA.PROYECTOID=@PROYECTOID
                                 ";

            _parametrosConsulta.Add("@PROYECTOID", proyectoId);
        }
        public void FiltrarPorUsuarioInteresadoId(string usuarioInteresadoId)
        {
            _where += @"AND EXISTS 
                        (   
                            SELECT 1 
                            FROM INTERESADOPAQUETETRABAJO [INTPAQ] 
                            WHERE INTPAQ.PAQUETETRABAJOID=PA.ID 
                            AND INTPAQ.USUARIOINTERESADOID=@USUARIOINTERESADOID
                        )
                        ";

            _parametrosConsulta.Add("@USUARIOINTERESADOID", usuarioInteresadoId);
        }

        public void FiltrarPorRolUsuarioInteresadoId(string rolId)
        {
            _where += @"AND EXISTS 
                        (   
                            SELECT 1 FROM PERMISOROLPAQUETETRABAJO [PERPAQ]
                            WHERE PERPAQ.ROLID=@ROLID
                            AND PERPAQ.ESTADOPAQUETETRABAJOID=PA.ESTADOPAQUETETRABAJOID
                            AND PERPAQ.PERMISO>@PERMISODENEGAR
                        )
                        ";

            _parametrosConsulta.Add("@ROLID", rolId);
            _parametrosConsulta.Add("@PERMISODENEGAR", ConvertFormat.Char_To_Integer(Parametros.Permiso_Denegar));
        }
        public void FiltrarPorCodigoCuentaLike(string codigoCuenta)
        {
            _where += @"AND PA.CODIGOCUENTA LIKE @CODIGOCUENTA + '%' 
                        ";

            _parametrosConsulta.Add("@CODIGOCUENTA", codigoCuenta);
        }
        public void FiltrarPorNombre(string nombre)
        {
            _where += @"AND PA.NOMBRE LIKE '%' + @NOMBRE + '%' 
                        ";

            _parametrosConsulta.Add("@NOMBRE", nombre);
        }
        public void FiltrarPorTipoPaqueteTrabajoId(string tipoPaqueteTrabajoId)
        {
            _where += @"AND PA.TIPOPAQUETETRABAJOID = @TIPOPAQUETETRABAJOID
                        ";

            _parametrosConsulta.Add("@TIPOPAQUETETRABAJOID", tipoPaqueteTrabajoId);
        }
        public void FiltrarPorEstadoPaqueteTrabajoId(string estadoPaqueteTrabajoId)
        {
            _where += @"AND PA.ESTADOPAQUETETRABAJOID = @ESTADOPAQUETETRABAJOID
                        ";

            _parametrosConsulta.Add("@ESTADOPAQUETETRABAJOID", estadoPaqueteTrabajoId);
        }
        public void FiltrarPorUsuarioResponsableId(string usuarioResponsableId)
        {
            _where += @"AND PA.USUARIORESPONSABLEID = @USUARIORESPONSABLEID
                        ";

            _parametrosConsulta.Add("@USUARIORESPONSABLEID", usuarioResponsableId);
        }
        public void FiltrarPorUsuarioAsignadoId(string usuarioAsignadoId)
        {
            _where += @"AND PA.USUARIOASIGNADOID = @USUARIOASIGNADOID
                        ";

            _parametrosConsulta.Add("@USUARIOASIGNADOID", usuarioAsignadoId);
        }
        public void FiltrarPorSinAsignacion()
        {
            _where += @"AND PA.USUARIOASIGNADOID IS NULL
                        ";
        }
        public void FiltrarPorFechaInicioProyectado(DateTime fechaDesde, DateTime fechaHasta)
        {
            _where += @"AND
                        ( 
                            PA.FECHAINICIOPROYECTADO >= @FECHADESDE
                            AND 
                            PA.FECHAINICIOPROYECTADO < @FECHAHASTA
                        )
                        ";

            _parametrosConsulta.Add("@FECHADESDE", fechaDesde);
            _parametrosConsulta.Add("@FECHAHASTA", fechaHasta);
        }
        public void FiltrarPorFechaFinProyectado(DateTime fechaDesde, DateTime fechaHasta)
        {
            _where += @"AND
                        ( 
                            PA.FECHAFINPROYECTADO>= @FECHADESDE
                            AND 
                            PA.FECHAFINPROYECTADO < @FECHAHASTA
                        )
                        ";

            _parametrosConsulta.Add("@FECHADESDE", fechaDesde);
            _parametrosConsulta.Add("@FECHAHASTA", fechaHasta);
        }

        public void FiltrarPorFechaInicioReal(DateTime fechaDesde, DateTime fechaHasta)
        {
            _where += @"AND
                        ( 
                            PA.FECHAINICIOREAL >= @FECHADESDE
                            AND 
                            PA.FECHAINICIOREAL < @FECHAHASTA
                        )
                        ";

            _parametrosConsulta.Add("@FECHADESDE", fechaDesde);
            _parametrosConsulta.Add("@FECHAHASTA", fechaHasta);
        }
        public void FiltrarPorFechaFinReal(DateTime fechaDesde, DateTime fechaHasta)
        {
            _where += @"AND
                        ( 
                            PA.FECHAFINREAL >= @FECHADESDE
                            AND 
                            PA.FECHAFINREAL < @FECHAHASTA
                        )
                        ";

            _parametrosConsulta.Add("@FECHADESDE", fechaDesde);
            _parametrosConsulta.Add("@FECHAHASTA", fechaHasta);
        }


        #endregion
    }
}
